<template>
	<div style="width: 100%;">
		<div style="width: 100%;color: orange;margin-bottom: 10px;">
			<slot></slot>
		</div>
		<div style="width: 100%;" v-loading="loading">
			<el-table ref="table" :data="filterTableData"
					  :size="size"
					  :border="border"
					  :stripe="stripe"
					   row-key="id"
					  :height="height?height:this.tableHeight"
					  :max-height="maxHeight?maxHeight:null"
					  :table-layout="tableLayout"
					  :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
					  lazy
					  :load="lazyLoad"
					  @selection-change="selectionChange"
					  :default-expand-all="false"
					  style="width: 100%;height:100%;">
				<el-table-column type="selection" width="40" :selectable="selectInit"/>
				<template v-for="column in this.defaultColumns" :key="column.code">
					<el-table-column :prop="column.code"
									 :label="column.name"
									 :align="column.align?column.align:'left'"
									 :sortable="column.sortable?column.sortable:false"
									 :formatter="this.formatter"
									 :column-key="column.code"
									 :show-overflow-tooltip="true"
									 :width="column.width?column.width:null">

					</el-table-column>
				</template>
<!--        <el-table-column align="right">-->
<!--          <template #header>-->
<!--            <el-input v-model="search" size="small" placeholder="Type to search" />-->
<!--          </template>-->
<!--        </el-table-column>-->

				<template v-slot:empty>
					<el-empty description=" "></el-empty>
				</template>
			</el-table>
		</div>
	</div>
</template>

<script>

import tool from "@/utils/tool";

export default {
	name: "exRelTable",
	props: {
		stripe: {type: Boolean, default: true},
		border: {type: Boolean, default: true},
		selection: {type: Boolean, default: true},
		defaultExpandAll: {type: Boolean, default: false},
		height: {type: Number, default: null},
		maxHeight: {type: Number, default: null},
		tableLayout: {type: String, default: 'fixed'},//fixed,autos
		size: {type: String, default: "default"},//large / default /small
		treeApi: {type: Object, default: {}},//数据加载的url
		relEntity: {type: Object, default: null},//实体对象
		name: {type: String, default: null},//关联对象的实体名称
		columns: {type: Array, default: null},
	},
	components: {},
	data() {
		return {
			loading: false,
			records: [],
			ori_records:[],
			tableHeight: null,
			search:"",
			defaultColumns: [
				{code: "code", name: this.$t("common.ex_tree_table_column_code"), width: "200"},
				{code: "label", name: this.$t("common.ex_tree_table_column_name"), width: ""},
			],
			entityName: null,
		}
	},
	watch: {
    search(newVal){
    }
  },
	computed: {
    filterTableData:function(){
      return this.records.filter(
          (record) => !this.search || record.label.includes(this.search)
      );
    }
  },
	created() {
	},
	mounted() {
		this.resetTableHeight();
		this.refresh();
		window.addEventListener("resize",this.resetTableHeight);
	},
	unmounted() {
		window.removeEventListener("resize",this.resetTableHeight);
	},
	methods: {
		lazyLoad(tree, treeNode, resolve){
			let tempRecords = [];
			if(treeNode.level===0){
				this.ori_records.forEach(item=>{
					if(item.id===tree.id){
						tempRecords = item.children;
					}
				})
			}else{
				tempRecords = tree._children;
			}
			tempRecords.forEach(item => {
				item.hasChildren = item.children && item.children.length > 0;
				item._children = item.children;
				item.children = [];
			});
			resolve(tempRecords);
			tree.children = tempRecords;
			this.initSelections();
		},

		resetTableHeight() {
			let h = 15;
			let height = this.$parent.$el.clientHeight - h;
			if (height <= 300) {
				this.tableHeight = 300;
			} else {
				this.tableHeight = height;
			}
		},
		selectInit(row) {
			if (row.isEnabled === '0' && row.children) {
				row.children.forEach(item => {
					item.isEnabled = row.isEnabled;
				});
			}
			return row.isEnabled === '1';
		},
		selectionChange(val) {
			let rows = [];
			val.forEach(item => {
				if (item.isEnabled === '1') {
					rows.push(item);
				} else {
					//去除状态不可用行的选中状态
					this.$refs.table.toggleRowSelection(item, false);
				}
			});


      //获取所有选中的ID
      let selections = {};
      rows.forEach(item => {
        selections[item.id]=true;
      });

      //所有未选中的id
      let copyRecords = this.$TOOL.objCopy(this.records);
      let filter = this.filterParentNode(rows,copyRecords);

      //去除未全选的父节点
      for (let filterId in filter){
        delete selections[filterId];
      }
      //设置映射关系
      let relMap = {};
      relMap[this.entityName] = [];
      for (let selectionId in selections){
          relMap[this.entityName].push(selectionId);
      }
			//赋值
			if(this.relEntity){
				if (!this.relEntity.relMaps) {
					this.relEntity.relMaps = {};
				}
				this.relEntity.relMaps[this.entityName] = {};
				//重新赋值新数据
				Object.assign(this.relEntity.relMaps, relMap);
			}

			// this.$emit("relHandler", relMap);
		},
    filterParentNode(rows,records){
      let filter = {};
      records.forEach(item => {
        if(item.children){
          let childFilter = this.filterParentNode(rows,item.children);
          Object.assign(filter,childFilter);
          item.children.forEach(child=>{
            rows.forEach(row=>{
              if(row.id===child.id){
                child.selected = true;
              }
            });
            if(child.selected!==true){//若子节点没有选中
              filter[child.id] = false;
              filter[item.id] = false;
            }
          });
        }else{
          rows.forEach(row=>{
            if(row.id===item.id){
              item.selected = true;
            }
          });

          if(item.selected!==true){//若子节点没有选中
            filter[item.id] = false;
          }
        }
      });
      return filter;
    },
		setTableData(data) {
			this.ori_records = this.$TOOL.objCopy(data);
			let tempRecords = [];
			//优先取设置的名称
			this.entityName=this.name;
			data.forEach(item => {
				item.hasChildren = item.children&&item.children.length>0;
				if (!this.entityName) {
					this.entityName = item.entityName;
				}
				item.children=[];
				tempRecords.push(item);
			});
			this.records = tempRecords;
			this.initSelections();
		},
		async initSelections() {
			if (this.relEntity && this.relEntity.id) {
				let queryDto = {
					firstEntity: this.relEntity.entityName,
					firstEntityId: this.relEntity.id,
					secondEntity: this.entityName,
				};
				let rsp = await this.$API.system.relMap.load.post(queryDto);
				if (rsp.fail) {
					this.$message.warning(this.$t('common.rel_map_data_load_fail'));
					return;
				}
				if (rsp.data) {
					//默认选中所有
					this.records.forEach(record => {
						this.$refs.table.toggleRowSelection(record, true);
					});
					//剔除未选中的项
					let notExists = [];
					this.records.forEach(record => {
						let selected = this.removeSelection(record, rsp.data);
						if (selected.count === 0) {
							notExists.push(record);
						}
					});
					if (!this.selection) {
						notExists.forEach(item => {
							this.records = this.records.filter(record => record.id !== item.id);
						});
					}
				}
			}
		},
		removeSelection(record, data) {
			let selected = {count: 0};
			data.forEach(item => {
				if (record.id === item.secondEntityId) {
					selected.count++;
				}
			});
			let notExists = [];
			if (record.children) {
				record.children.forEach(item => {
					let childSelected = this.removeSelection(item, data);
					selected.count = selected.count + childSelected.count;
					if (childSelected.count === 0) {
						notExists.push(item);
					}
				});
			}
			if (this.selection) {
				if (selected.count === 0) {
					this.$refs.table.toggleRowSelection(record, false);
				}
			} else {
				notExists.forEach(item => {
					record.children = record.children.filter(child => child.id !== item.id);
				})
			}
			return selected;
		},
		async refresh(data) {
			this.loading = true;
			if (this.treeApi) {
				let queryParams = {parentLevelCode: '0000000'};
				//引入自定义参数
				if (data) {
					queryParams = Object.assign(queryParams, data);
				}
				//请求数据加载
				let result = await this.$cache.tree.reload(this.treeApi.storeName, queryParams);
				if (result) {
					this.setTableData(result);
				}
			}
			this.loading = false;
		},
		formatter(row, column, cellValue, index) {
			for (const item of this.defaultColumns) {
				if (item.code === column.property && item.formatter) {
					if (item.formatter instanceof Function) {
						cellValue = item.formatter(row, cellValue, this, index);
					} else {
						cellValue = tool.format.convert(cellValue, item.formatter, item.key);
					}
				}
			}
			return cellValue;
		},
	}
}
</script>
